import asyncio
import sys
from copy import deepcopy

import pygame

from debug import debug
from uiUtil import gameBgImg, drawText
from blocks import floor

bg = pygame.image.load('assets/img/bg.png')
# 定义图片
# 0：墙；1：假墙；2：楼梯上；3：地面；4：楼梯下；5：铁窗
img_wall = pygame.image.load('assets/img/builds/wall.png')
img_air_wall = pygame.image.load('assets/img/builds/airWall.png')
img_up = pygame.image.load('assets/img/builds/up.png')
img_grid = pygame.image.load('assets/img/grid.png')
img_down = pygame.image.load('assets/img/builds/down.png')
img_rail = pygame.image.load('assets/img/builds/rail.png')
# 10：黄门；11：蓝门；12：红门；13：假门；15：黄钥匙；16：蓝钥匙；17：红钥匙
img_yellow_gate = pygame.image.load('assets/img/builds/yellowGate.png')
img_blue_gate = pygame.image.load('assets/img/builds/blueGate.png')
img_red_gate = pygame.image.load('assets/img/builds/redGate.png')
img_green_gate = pygame.image.load('assets/img/builds/greenGate.png')
img_yellow_key = pygame.image.load('assets/img/items/yellowKey.png')
img_blue_key = pygame.image.load('assets/img/items/blueKey.png')
img_red_key = pygame.image.load('assets/img/items/redKey.png')
# 20：红药瓶；21：蓝药瓶；25：红宝石，26：蓝宝石
img_hp = pygame.image.load('assets/img/items/hp.png')
img_hplarge = pygame.image.load('assets/img/items/hplarge.png')
img_attackgem = pygame.image.load('assets/img/items/attackgem.png')
img_defencegem = pygame.image.load('assets/img/items/defencegem.png')
# 30：绿史莱姆；31：红史莱姆；32：蓝蝙蝠；33：骷髅；34：盾牌骷髅；35：法师；
img_monster01 = pygame.image.load('assets/img/monsters/monster01.png')
img_monster02 = pygame.image.load('assets/img/monsters/monster02.png')
img_monster03 = pygame.image.load('assets/img/monsters/monster03.png')
img_monster05 = pygame.image.load('assets/img/monsters/monster05.png')
img_monster06 = pygame.image.load('assets/img/monsters/monster06.png')
img_monster04 = pygame.image.load('assets/img/monsters/monster04.png')
# 41：中级卫兵
img_monster21 = pygame.image.load('assets/img/monsters/monster21.png')
# 60：智者；61：商人；62：小偷
img_wise = pygame.image.load('assets/img/npc/wise.png')
img_business = pygame.image.load('assets/img/npc/business.png')
img_thief = pygame.image.load('assets/img/npc/thief.png')
# 70：楼梯道具；
img_chuansong = pygame.image.load('assets/img/items/chuansong.png')
# 90：金币；91：血量；92：铁剑；93：铁盾；99：英雄；
img_luckycoins = pygame.image.load('assets/img/items/luckycoins.png')
img_tiejian = pygame.image.load('assets/img/items/tiejian.png')
img_tiedun = pygame.image.load('assets/img/items/tiedun.png')
img_player_icon = pygame.image.load('assets/img/player_icon.png')

# 加载原始地图
floorMap = deepcopy(floor)

# 0：墙；1：假墙；2：楼梯上；3：地面；4：楼梯下；5：铁窗
# 10：黄门；11：蓝门；12：红门；13：假门；15：黄钥匙；16：蓝钥匙；17：红钥匙
# 20：红药瓶；21：蓝药瓶；25：红宝石，26：蓝宝石
# 30：绿史莱姆；31：红史莱姆；32：蓝蝙蝠；33：骷髅；34：盾牌骷髅；35：初级法师；
# 41：中级卫兵
# 60：智者；61：商人；62：小偷
# 70：楼梯道具；
# 90：金币；91：血量；92：铁剑；93：铁盾；99：英雄；

# 用于保存英雄的坐标
hero = [11, 6]
# 拥有的钥匙数量：黄，蓝，红
keys = [0,0,0]
# 英雄信息
heroInfo = [{"img":91,"value":500},{"img":92,"value":10},{"img":93,"value":10},{"img":90,"value":0}]
# 怪物信息
monsterInfos = [{"name":"绿色史莱姆","hp":35,"attack":18,"defense":1,"gold":1},
               {"name":"红色史莱姆","hp":45,"attack":20,"defense":2,"gold":2},
               {"name":"蓝蝙蝠","hp":35,"attack":38,"defense":3,"gold":3},
               {"name":"骷髅","hp":50,"attack":42,"defense":6,"gold":6},
               {"name":"盾牌骷髅","hp":55,"attack":52,"defense":12,"gold":8},
               {"name":"初级法师","hp":60,"attack":32,"defense":8,"gold":5}]

class MainTower:

    def __init__(self, dims, FPS=60):
        self.dims = dims
        self.FPS = FPS
        # 游戏运行控制变量（gamen_running）
        self.game_running = True
        self.score = 0
        # 当前楼层
        self.current_floor = 1

    def switch(self, case):
        cases = {
            0: img_wall,1: img_air_wall,2: img_up,3: img_grid,4: img_down,5:img_rail,
            10: img_yellow_gate,11: img_blue_gate,12: img_red_gate,13: img_green_gate,15: img_yellow_key,16: img_blue_key,17: img_red_key,
            20: img_hp,21: img_hplarge,25: img_attackgem,26: img_defencegem,
            30: img_monster01,31: img_monster02,32: img_monster03,33: img_monster05,34: img_monster06,35: img_monster04,
            41: img_monster21,
            60: img_wise,61: img_business,62: img_thief,
            70: img_chuansong,
            90: img_luckycoins,91: img_hp,92:img_tiejian,93:img_tiedun,99: img_player_icon
        }
        return cases.get(case, 'default Case')

    # 画地图
    def drawGameMap(self, screen, map_block_list):
        for row in range(13):
            for col in range(13):
                currentImg = self.switch(map_block_list[row][col])
                # 画出对应的图片
                screen.blit(pygame.transform.scale(img_grid, (50, 50)), (col * 50, row * 50))
                screen.blit(pygame.transform.scale(currentImg,(50, 50)),(col * 50, row * 50))

    # 控制角色移动
    def heroMove(self, direction, map_block_list):
        if self.canMove(direction, map_block_list):
            map_block_list[hero[0]][hero[1]] = 3  # 原先的地方变成路
            if direction == "left":
                hero[1] -= 1
            if direction == "right":
                hero[1] += 1
            if direction == "up":
                hero[0] -= 1
            if direction == "down":
                hero[0] += 1
            map_block_list[hero[0]][hero[1]] = 99

    # 判断角色是否可以移动
    def canMove(self, direction, map_block_list):
        # 碰撞检测
        result = False
        if direction == "left":
            result = self.collisionDetection(hero[0], hero[1]-1, map_block_list)
        if direction == "right":
            result = self.collisionDetection(hero[0], hero[1]+1, map_block_list)
        if direction == "up":
            result = self.collisionDetection(hero[0]-1, hero[1], map_block_list)
        if direction == "down":
            result = self.collisionDetection(hero[0]+1, hero[1], map_block_list)
        return result
    # 碰撞检测
    def collisionDetection(self, expect_row, expect_col, map_block_list):
        if map_block_list[expect_row][expect_col] == 2:#楼梯上
            self.current_floor += 1
            # 将英雄放到新楼层
            floorMap[self.current_floor][hero[0]][hero[1]] = 99
            return False
        if map_block_list[expect_row][expect_col] == 4:#楼梯下
            self.current_floor -= 1
            # 将英雄放到新楼层
            floorMap[self.current_floor][hero[0]][hero[1]] = 99
            return False
        if map_block_list[expect_row][expect_col] == 0:#墙
            return False
        if map_block_list[expect_row][expect_col] == 1:#假墙
            return True
        if map_block_list[expect_row][expect_col] == 3:#路
            return True
        if map_block_list[expect_row][expect_col] == 10:#黄门
            # 判断手里有几把黄钥匙,如果有，减一把
            if keys[0] > 0:
                keys[0] -= 1
                return True
            else:
                return False
        if map_block_list[expect_row][expect_col] == 11:#蓝门
            # 判断手里有几把黄钥匙,如果有，减一把
            if keys[1] > 0:
                keys[1] -= 1
                return True
            else:
                return False
        if map_block_list[expect_row][expect_col] == 12:#红门
            # 判断手里有几把黄钥匙,如果有，减一把
            if keys[2] > 0:
                keys[2] -= 1
                return True
            else:
                return False
        if map_block_list[expect_row][expect_col] == 15:#黄钥匙
            keys[0] += 1
            return True
        if map_block_list[expect_row][expect_col] == 16:#蓝钥匙
            keys[1] += 1
            return True
        if map_block_list[expect_row][expect_col] == 17:#红钥匙
            keys[2] += 1
            return True
        if map_block_list[expect_row][expect_col] == 20:#红血瓶，血+50
            heroInfo[0]["value"] = heroInfo[0]["value"] + 50
            return True
        if map_block_list[expect_row][expect_col] == 21:#蓝血瓶，血+200
            heroInfo[0]["value"] = heroInfo[0]["value"] + 200
            return True
        if map_block_list[expect_row][expect_col]>=30 and map_block_list[expect_row][expect_col]<60:
            # 计数伤害
            monsterInfo = monsterInfos[map_block_list[expect_row][expect_col]-30]
            # {"name":"绿色史莱姆","hp":35,"attack":18,"defense":1,"gold":1
            hp = monsterInfo["hp"]
            attack = monsterInfo["attack"]
            defense = monsterInfo["defense"]
            gold = monsterInfo["gold"]
            # heroInfo = [{"img":91,"value":1000},{"img":92,"value":100},{"img":93,"value":100},{"img":90,"value":0}]
            hero_hp = heroInfo[0]["value"]
            hero_attack = heroInfo[1]["value"]
            hero_defense = heroInfo[2]["value"]
            hero_gold = heroInfo[3]["value"]
            # 开始计算
            _hp = hp - (hero_attack - defense)  # 一回合后怪物血量
            _herohp = hero_hp
            while _hp>0:
                _herohp = _herohp - (attack-hero_defense) # 一回合后英雄血量
                _hp = _hp - (hero_attack - defense)  # 一回合后怪物血量
            if _herohp>0:
                heroInfo[0]["value"] = _herohp
                heroInfo[3]["value"] = hero_gold + gold
                return True
            else:
                return False


        return True

    # 显示英雄信息
    def drawHeroInfo(self, screen):
        self.drawInfo(screen, img_yellow_key, keys[0], (20, 700))
        self.drawInfo(screen, img_blue_key, keys[1], (20, 750))
        self.drawInfo(screen, img_red_key, keys[2], (20, 800))
        # heroInfo = {"hp":"1000","harm":100,"def":100,"gold":0}
        for i in range(4):
            self.drawInfo(screen, self.switch(heroInfo[i]["img"]), heroInfo[i]["value"], (20, 850 + 50 * i))

    def drawInfo(self, screen, img, msg, position):
        screen.blit(pygame.transform.scale(img, (40, 40)), position)
        drawText(f"{msg}", "black", (position[0] + 80, position[1]), screen)
    async def start(self):
        # 初始化pygame，预定义各种常量
        pygame.init()
        # 初始化游戏界面（screen）：尺寸、背景色等
        screen = pygame.display.set_mode(self.dims)
        # 显示游戏名称
        pygame.display.set_caption("魔塔50层")
        # 初始化游戏时钟（clock），由于控制游戏帧率
        clock = pygame.time.Clock()
        # 播放背景音乐
        # playMyBgMusic('')

        # 游戏主循环
        while True:
            # 按照给定的 FPS 刷新游戏
            # clock.tick() 函数返回上一次调用该函数后经历的时间，单位为毫秒 ms
            # dt 记录上一帧接受之后经历的时间，单位为秒 m
            # 使用 dt 控制物体运动可以使游戏物理过程与帧率无关
            dt = clock.tick(self.FPS) / 1000.0
            # 使用 asyncio 同步
            # 此外游戏主体代码中不需要再考虑 asyncio
            await asyncio.sleep(0)

            # 游戏事件处理
            # 包括键盘、鼠标输入等
            for event in pygame.event.get():
                # 点击关闭窗口按钮或关闭网页
                if event.type == pygame.QUIT:
                    pygame.quit()
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_LEFT:
                        self.heroMove("left", floorMap[self.current_floor])
                    if event.key == pygame.K_RIGHT:
                        self.heroMove("right", floorMap[self.current_floor])
                    if event.key == pygame.K_UP:
                        self.heroMove("up", floorMap[self.current_floor])
                    if event.key == pygame.K_DOWN:
                        self.heroMove("down", floorMap[self.current_floor])


            # 以背景色覆盖刷新游戏界面
            gameBgImg(screen, bg, 270, self.dims)
            # 调用 debug 函数在游戏界面左上角显示游戏帧率
            # debug(f"{clock.get_fps():.1f}", 20, 10, color='green')
            # 显示分数
            # drawText(f'魔塔50层', "black", (20, 50), screen)
            # 绘制地图
            self.drawGameMap(screen, floorMap[self.current_floor])
            self.drawHeroInfo(screen)

            # 将游戏界面内容输出至屏幕
            pygame.display.update()

            # 跳出游戏主循环，退出游戏
        cfg.inGame = False

if __name__ == '__main__':
    print(sys.version)
    asyncio.run(MainTower((720, 1280), FPS = 30).start())